﻿// // This code is released under the BSD license.
namespace PugLib
{
	using System;
	using System.Diagnostics.CodeAnalysis;

	using Extensions;

	/// <summary>
	/// A wrapper that raises an event when the state/value changes.
	/// </summary>
	/// <typeparam name="T"></typeparam>
	public class NotifyChanged<T>
	{
		private T _state;

		public NotifyChanged()
		{
		}

		public NotifyChanged(T state)
		{
			_state = state;
		}

		/// <summary>
		/// Value set if and only if the new value's reference is not equal to the old value
		/// </summary>
		public T State
		{
			get { return _state; }
			set
			{
				if (ReferenceEquals(_state, value))
				{
					return;
				}
				_state = value;
				StateChanged.Raise(this, new StateChangedEventArgs<T>(State));
			}
		}

		public event EventHandler<StateChangedEventArgs<T>> StateChanged;
	}

	public static class NotifyChanged
	{
		[SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter", Justification = "factory method")]
		public static NotifyChanged<T> Create<T>()
		{
			return new NotifyChanged<T>(Activator.CreateInstance<T>());
		}

		[SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "factory method")]
		public static NotifyChanged<T> Create<T>(EventHandler<StateChangedEventArgs<T>> changeEvent)
		{
			NotifyChanged<T> x = Create<T>();
			x.StateChanged += changeEvent;
			return x;
		}
	}
}